//
//  JMAntiLostAes128.m
//  LockUncleUser
//
//  Created by zhangjiaming on 16/5/31.
//  Copyright © 2016年 zhangjiaming. All rights reserved.
//

#import "JMAntiLostAes128.h"
#import <CommonCrypto/CommonCryptor.h>

#define gkey @"1122334455667788"

@implementation JMAntiLostAes128

/** 将传入的data加密 */
+ (NSMutableData *)antiLostAes128Encrypt:(NSData *)encryptData {
    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    
    // fetch key data
    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCBlockSizeAES128 + 1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [gkey getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [encryptData length];
    
    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    unsigned long newSize = 0;
    
    if(diff > 0) {
        newSize = dataLength + diff;
    }
    
    char dataPtr[newSize];
    memcpy(dataPtr, [encryptData bytes], [encryptData length]);
    for(int i = 0; i < diff; i++) {
        // 这里是关键，这里是使用NoPadding的
        dataPtr[i + dataLength] = 0x0000;
    }
    
    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    memset(buffer, 0, bufferSize);
    
    size_t numBytesEncrypted = 0;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, // kCCEncrypt为加密，kCCDecrypt为解密
                                          kCCAlgorithmAES128, // 加密的算法
                                          kCCOptionECBMode, // ECB模式或PKCS7Padding模式
                                          [gkey UTF8String], // 加密/解密的密钥
                                          kCCKeySizeAES128, // 密钥的长度
                                          ivPtr,            // 是个固定值，通过直接使用密钥即可。注视这个参数，如果安卓、服务端和iOS端不统一，那么加密结果就会不一样，解密可能能解出来，但是解密后在末尾会出现一些\0、\t之类的。
                                          dataPtr, // 加密/解密的数据
                                          sizeof(dataPtr), // 加密/解密的数据的长度
                                          buffer, // 接收加密后/解密后的结果
                                          bufferSize, // 加密后/解密后的数据的长度
                                          &numBytesEncrypted); // 实际加密/解密的数据的长度
    
    
    if (cryptStatus == kCCSuccess) {
        return [NSMutableData dataWithBytesNoCopy:buffer length:16];
    }
    
    free(buffer); //free the buffer;
    return nil;
}

/** 解密 */
+ (NSMutableData *)antiLostAes128Decrypt:(NSData *)decryptData {
    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    
    [gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCBlockSizeAES128 + 1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [gkey getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [decryptData length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesCrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionECBMode,
                                          [gkey UTF8String],
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [decryptData bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    
    if (cryptStatus == kCCSuccess) {
        NSMutableData *resultData = [NSMutableData dataWithBytesNoCopy:buffer length:16];
        return resultData;
    }
    
    free(buffer); //free the buffer;
    return nil;
}

@end
